package com.xiaocz.hblsubstitutedriving.socket;

import com.vise.log.ViseLog;
import com.xiaocz.hblsubstitutedriving.interfaces.MainUtils;
import com.xiaocz.hblsubstitutedriving.utils.Constants;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

/**
 * Created by shensky on 2018/1/15.
 */

public class TaskCenter {
    private static TaskCenter instance;
    //    Socket
    private static Socket socket;
    private Thread thread;
    //    Socket输出流
    private OutputStream outputStream;
    //    Socket输入流
    private InputStream inputStream;
    //    连接回调
    private OnServerConnectedCallbackBlock connectedCallback;
    //    断开连接回调(连接失败)
    private OnServerDisconnectedCallbackBlock disconnectedCallback;
    //    接收信息回调
    private OnReceiveCallbackBlock receivedCallback;

    //    构造函数私有化
    private TaskCenter() {
        super();
    }

    //    提供一个全局的静态方法
    public static TaskCenter sharedCenter() {
        if (instance == null) {
            synchronized (TaskCenter.class) {
                if (instance == null) {
                    instance = new TaskCenter();
                }
            }
        }
        return instance;
    }

    public void startSocket(final String data) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                if (socket != null) {
                    try {
                        outputStream.write(data.getBytes());
                        outputStream.flush();
                        System.out.println("--socket开启成功");
                    } catch (IOException e) {
                        e.printStackTrace();
                        System.out.println("--socket开启失败");
                    }
                } else {
                    connect();
                }
            }
        }).start();
    }

    /**
     * 停止socket
     */
    public void stopSocket() {
        releaseSocket();
        removeCallback();
    }

    private void getSocket() {
        if (socket == null) {
            try {
                socket = new Socket(Constants.TCP_IP, Constants.TCP_PORT);
                socket.setSoTimeout(10 * 1000);//设置超时时间
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 通过IP地址(域名)和端口进行连接
     */
    private void connect() {
        thread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    getSocket();
                    if (socket.isConnected()) {
                        if (connectedCallback != null) {
                            connectedCallback.callback();
                        }
                        outputStream = socket.getOutputStream();
                        inputStream = socket.getInputStream();
                        receive();
                        ViseLog.i("连接成功");
                    } else {
                        ViseLog.e("连接失败");
                        if (disconnectedCallback != null) {
                            disconnectedCallback.callback(new IOException("连接失败"));
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    ViseLog.e("连接异常");
                    if (disconnectedCallback != null) {
                        disconnectedCallback.callback(e);
                    }
                    releaseSocket();
                }
            }
        });
        thread.start();
    }

    /**
     * 重置socket
     */
    public void releaseSocket() {
        if (outputStream != null) {
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            outputStream = null;
        }
        if (inputStream != null) {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            inputStream = null;
        }
        if (socket != null) {
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            socket = null;
        }
        Constants.isWork = false;
    }

    /**
     * 接收数据
     */
    public void receive() {
        while (socket.isConnected() && inputStream != null) {
            try {
                /**得到的是16进制数，需要进行解析*/
                byte[] bt = new byte[10 * 1024];
                //获取接收到的字节和字节数
                int length = inputStream.read(bt);
                //获取正确的字节
                String response = new String(bt, 0, length);
                if (receivedCallback != null) {
                    receivedCallback.callback(response);
                }
                ViseLog.i("接收成功" + response);
                i = 0;
            } catch (IOException e) {
                i++;
                ViseLog.e("接收失败");
                if (i == 6) {
                    MainUtils.onMainRefresh(2, "接收失败");
                    TaskCenter.sharedCenter().releaseSocket();
                    TaskCenter.sharedCenter().startSocket("开始听单");
                    i = 0;
                }
            }
        }
    }

    private int i = 0;

    public void sendMessage(String method, String content) {
        send(String.format("%s&%s\r\n", method, content));
    }

    /**
     * 发送数据
     *
     * @param data 数据
     */
    private void send(final String data) {
        if (Constants.isRelink) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    if (socket != null && outputStream != null) {
                        try {
                            String str = new String(data.getBytes(), StandardCharsets.UTF_8);
                            ViseLog.i("--发送内容：" + str);
                            if (!"".equals(str)) {
                                outputStream.write(str.getBytes());
                                outputStream.flush();
                                ViseLog.i("发送成功");
                            } else {
                                ViseLog.i("发送失败");
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                            ViseLog.i("发送失败");
                        }
                    } else {
                        connect();
                    }
                }
            }).start();
        }
    }

    /**
     * 回调声明
     */
    public interface OnServerConnectedCallbackBlock {
        void callback();
    }

    public interface OnServerDisconnectedCallbackBlock {
        void callback(Exception e);
    }

    public interface OnReceiveCallbackBlock {
        void callback(String receicedMessage);
    }

    public void setConnectedCallback(OnServerConnectedCallbackBlock connectedCallback) {
        this.connectedCallback = connectedCallback;
    }

    public void setDisconnectedCallback(OnServerDisconnectedCallbackBlock disconnectedCallback) {
        this.disconnectedCallback = disconnectedCallback;
    }

    public void setReceivedCallback(OnReceiveCallbackBlock receivedCallback) {
        this.receivedCallback = receivedCallback;
    }

    /**
     * 移除回调
     */
    private void removeCallback() {
        connectedCallback = null;
        disconnectedCallback = null;
        receivedCallback = null;
    }
}
